home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / amiga / plotting / gnuplot3.lzh / gnuplot / gnuplot_x11.c < prev    next >
C/C++ Source or Header  |  1991-09-09  |  9KB  |  264 lines

  1. /*-----------------------------------------------------------------------------
  2.  *   gnuplot_x11 - X11 outboard terminal driver for gnuplot 3
  3.  *
  4.  *   Requires installation of companion inboard x11 driver in gnuplot/term.c
  5.  *
  6.  *   Acknowledgements: 
  7.  *      Chris Peterson (MIT) - original Xlib gnuplot support (and Xaw examples)
  8.  *      Dana Chee (Bellcore)  - mods to original support for gnuplot 2.0
  9.  *      Arthur Smith (Cornell) - graphical-label-widget idea (xplot)
  10.  *      Hendri Hondorp (University of Twente, The Netherlands) - Motif xgnuplot
  11.  *
  12.  *   This code is provided as is and with no warranties of any kind.
  13.  *       
  14.  *   Ed Kubaitis - Computing Services Office -  University of Illinois, Urbana
  15.  *---------------------------------------------------------------------------*/
  16.  
  17. #include <stdio.h>
  18. #include <signal.h>
  19. #include <X11/Intrinsic.h>
  20. #include <X11/StringDefs.h>
  21. #include <Label.h>          /* use -Idir for location on your system */
  22. #ifdef MOTIF
  23. #include <Xm.h>             /* use -Idir for location on your system */
  24. #define LabelWC xmLabelWidgetClass
  25. #define LabelBPM XmNbackgroundPixmap
  26. #else
  27. #define LabelWC labelWidgetClass
  28. #define LabelBPM XtNbitmap
  29. #endif
  30.  
  31. #define Color (D>1)
  32. #define Ncolors 11
  33. unsigned long colors[Ncolors];
  34. char color_keys[Ncolors][30] =   { "text", "border", "axis", 
  35.    "line1", "line2", "line3", "line4", "line5", "line6", "line7", "line8" };
  36. char color_values[Ncolors][30] = { "black", "black", "black", 
  37.    "red",  "green", "blue",  "magenta", "cyan", "sienna", "orange", "coral" };
  38.  
  39. char dashes[10][5] = { {0}, {1,6,0}, 
  40.    {0}, {4,2,0}, {1,3,0}, {4,4,0}, {1,5,0}, {4,4,4,1,0}, {4,2,0}, {1,3,0}
  41.    };
  42.  
  43. Widget w_top, w_label; Window win; Display *dpy;
  44. Pixmap pixmap;  GC gc = (GC)NULL;
  45. Dimension W = 640 , H = 450;  int D;
  46. Arg args[5];
  47. static void gnuplot(), resize();
  48.  
  49. int cx=0, cy=0, vchar, nc = 0, ncalloc = 0;
  50. double xscale, yscale;
  51. #define X(x) (Dimension) (x * xscale)
  52. #define Y(y) (Dimension) ((4095-y) * yscale)
  53. enum JUSTIFY { LEFT, CENTRE, RIGHT } jmode;
  54. #define Nbuf 1024
  55. char buf[Nbuf];
  56. String *commands = NULL;
  57.  
  58. typedef struct {       /* See "X Toolkit Intrinsics Programming Manual"      */
  59.   XFontStruct *font;   /* Nye and O'Reilly, O'Reilly & Associates, pp. 80-85 */
  60.   unsigned long fg;
  61.   unsigned long bg;
  62.   } RValues, *RVptr; 
  63. RValues rv;
  64.  
  65. XtResource resources[] = {
  66.    { XtNfont, XtCFont, XtRFontStruct, sizeof(XFontStruct *), 
  67.      XtOffset(RVptr, font), XtRString, "fixed" },
  68.    { XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel), 
  69.      XtOffset(RVptr, fg), XtRString, XtDefaultForeground },
  70.    { XtNbackground, XtCBackground, XtRPixel, sizeof(Pixel), 
  71.      XtOffset(RVptr, bg), XtRString, XtDefaultBackground },
  72.    };
  73.  
  74. /*-----------------------------------------------------------------------------
  75.  *   main program - fire up application and callbacks
  76.  *---------------------------------------------------------------------------*/
  77.  
  78. main(argc, argv) int argc; char *argv[]; {
  79.  
  80.    signal(SIGINT, SIG_IGN);
  81. #ifdef SIGTSTP
  82.    signal(SIGTSTP, SIG_IGN);
  83. #endif
  84.  
  85.    /* initialize application */
  86.    w_top = XtInitialize("gnuplot", "Gnuplot", NULL, 0, &argc, argv);
  87.    XtSetArg(args[0], XtNwidth, W);
  88.    XtSetArg(args[1], XtNheight, H);
  89.    w_label = XtCreateManagedWidget ("", LabelWC, w_top, args, (Cardinal)2);
  90.    XtRealizeWidget(w_top);
  91.  
  92.    /* extract needed information */
  93.    dpy = XtDisplay(w_top); win = XtWindow(w_label);
  94.    D = DisplayPlanes(dpy,DefaultScreen(dpy));
  95.    if (Color) {
  96.       char option[20], *value; 
  97.       XColor used, exact; int n;
  98.  
  99.       for(n=0; n<Ncolors; n++) {
  100.      strcpy(option, color_keys[n]);
  101.      strcat(option, "Color");
  102.      value = XGetDefault(dpy, "gnuplot", option);
  103.      if (!value) { value = color_values[n]; }
  104.      if (XAllocNamedColor(dpy, DefaultColormap(dpy,0), value, &used,&exact))
  105.         colors[n] = used.pixel; 
  106.      else {
  107.         fprintf(stderr, "gnuplot: cannot allocate %s:%s\n", option, value);
  108.         fprintf(stderr, "gnuplot: assuming %s:black\n", option);
  109.         colors[n] = BlackPixel(dpy,0);
  110.         }
  111.      }
  112.       }
  113.    XtSetArg(args[0], XtNwidth, &W);
  114.    XtSetArg(args[1], XtNheight,&H);
  115.    XtGetValues(w_label, args, (Cardinal)2);
  116.    XtGetApplicationResources(w_top, &rv, resources, XtNumber(resources),NULL,0);
  117.    vchar = (rv.font->ascent + rv.font->descent);
  118.  
  119.    /* add callbacks on input-from-gnuplot-on-stdin & window-resized */
  120.    XtAddInput(0, XtInputReadMask, gnuplot, NULL);
  121.    XtAddEventHandler(w_label, StructureNotifyMask, FALSE, resize, NULL);
  122.  
  123.    XtMainLoop();
  124.    }
  125.  
  126. /*-----------------------------------------------------------------------------
  127.  *   display - display accumulated commands from inboard driver
  128.  *---------------------------------------------------------------------------*/
  129.  
  130. display() {
  131.    int n, x, y, sw, sl, lt, width, type;
  132.    char *buf, *str;
  133.  
  134.    /* set scaling factor between internal driver & window geometry */
  135.    xscale = (double)W / 4096.;  yscale = (double)H / 4096.;  
  136.  
  137.    /* create new pixmap & GC */
  138.    if (gc) { XFreeGC(dpy, gc); XFreePixmap(dpy, pixmap); }
  139.    pixmap = XCreatePixmap(dpy, RootWindow(dpy,DefaultScreen(dpy)), W, H, D);
  140.    gc = XCreateGC(dpy, pixmap, 0, NULL);
  141.    XSetFont(dpy, gc, rv.font->fid);
  142.  
  143.    /* erase pixmap */
  144. #ifndef MOTIF
  145.    if (Color) { /* Athena needs different erase for color and mono */
  146. #endif
  147.       XSetForeground(dpy, gc, rv.bg);
  148.       XFillRectangle(dpy, pixmap, gc, 0, 0, W, H);
  149.       XSetForeground(dpy, gc, rv.fg);
  150.       XSetBackground(dpy, gc, rv.bg);
  151. #ifndef MOTIF
  152.       }
  153.    else {  
  154.       XSetFunction(dpy, gc, GXxor);
  155.       XCopyArea(dpy, pixmap, pixmap, gc, 0, 0, W, H, 0, 0);
  156.       XSetFunction(dpy, gc, GXcopyInverted);
  157.       }
  158. #endif
  159.  
  160.    /* connect new pixmap to label widget */
  161.    XtSetArg(args[0], LabelBPM, pixmap);
  162.    XtSetValues(w_label, args, (Cardinal)1);
  163.  
  164.    /* loop over accumulated commands from inboard driver */
  165.    for (n=0; n<nc; n++) {
  166.       buf = commands[n];
  167.  
  168.       /*   X11_vector(x,y) - draw vector  */
  169.       if (*buf == 'V') { 
  170.      sscanf(buf, "V%4d%4d", &x, &y);  
  171.      XDrawLine(dpy, pixmap, gc, X(cx), Y(cy), X(x), Y(y));
  172.      cx = x; cy = y;
  173.      }
  174.  
  175.       /*   X11_move(x,y) - move  */
  176.       else if (*buf == 'M') 
  177.      sscanf(buf, "M%4d%4d", &cx, &cy);  
  178.  
  179.       /*   X11_put_text(x,y,str) - draw text   */
  180.       else if (*buf == 'T') { 
  181.      sscanf(buf, "T%4d%4d", &x, &y);  
  182.      str = buf + 9; sl = strlen(str) - 1;
  183.      sw = XTextWidth(rv.font, str, sl);
  184.      switch(jmode) {
  185.         case LEFT:   sw = 0;     break;
  186.         case CENTRE: sw = -sw/2; break;
  187.         case RIGHT:  sw = -sw;   break;
  188.         }
  189.      if (!Color) 
  190.         XDrawString(dpy, pixmap, gc, X(x)+sw, Y(y)+vchar/3, str, sl);
  191.      else { 
  192.         XSetForeground(dpy, gc, colors[0]);
  193.         XDrawString(dpy, pixmap, gc, X(x)+sw, Y(y)+vchar/3, str, sl);
  194.         XSetForeground(dpy, gc, colors[lt+1]);
  195.         }
  196.      }
  197.  
  198.       /*   X11_justify_text(mode) - set text justification mode  */
  199.       else if (*buf == 'J') 
  200.      sscanf(buf, "J%4d", &jmode);
  201.  
  202.       /*   X11_linetype(type) - set line type  */
  203.       else if (*buf == 'L') { 
  204.      sscanf(buf, "L%4d", <);
  205.      lt = (lt%8)+2;
  206.      width = (lt == 0) ? 2 : 0;
  207.      if (Color) {
  208.         if (lt != 1) 
  209.            type = LineSolid;
  210.         else {
  211.            type = LineOnOffDash;
  212.            XSetDashes(dpy, gc, 0, dashes[lt], strlen(dashes[lt]));
  213.            }
  214.         XSetForeground(dpy, gc, colors[lt+1]);
  215.         }
  216.      else {
  217.         type  = (lt == 0 || lt == 2) ? LineSolid : LineOnOffDash;
  218.         if (dashes[lt][0])
  219.            XSetDashes(dpy, gc, 0, dashes[lt], strlen(dashes[lt]));
  220.         }
  221.      XSetLineAttributes( dpy,gc, width, type, CapButt, JoinBevel);
  222.      }
  223.       }
  224.  
  225.    /* trigger expose events to display pixmap */
  226.    XClearArea(dpy, win, 0, 0, 0, 0, True);
  227.    }
  228.  
  229. /*-----------------------------------------------------------------------------
  230.  *   gnuplot - Xt callback on input from gnuplot inboard X11 driver
  231.  *   resize - Xt callback when window resized
  232.  *---------------------------------------------------------------------------*/
  233.  
  234. static void
  235. gnuplot(cd, s, id) char *cd; int *s; XtInputId *id; {
  236.  
  237.    while (fgets(buf, Nbuf, stdin)) {
  238.      if (*buf == 'G') {                           /* enter graphics mode */
  239.      if (commands) {
  240.         int n; for (n=0; n<nc; n++) XtFree(commands[n]);
  241.         XtFree(commands);
  242.         }
  243.      commands = NULL; nc = ncalloc = 0;
  244.          }
  245.       else if (*buf == 'E') { display(); break; } /* leave graphics mode */
  246.       else if (*buf == 'R') { exit(0); }          /* leave X11/x11 mode  */
  247.       else {
  248.      if (nc >= ncalloc) {
  249.         ncalloc = ncalloc*2 + 1;
  250.         commands = (String *)XtRealloc(commands, ncalloc * sizeof(String));
  251.         }
  252.      commands[nc++] = XtNewString(buf);
  253.      }
  254.       }
  255.    if (feof(stdin) || ferror(stdin)) exit(0);
  256.    }
  257.  
  258. static void
  259. resize(w, cd, e) Widget w; char *cd; XConfigureEvent *e; {
  260.    if (e->type != ConfigureNotify) return;
  261.    W = e->width; H = e->height;
  262.    display(); 
  263.    }
  264.